﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

namespace ZX_AAA_Workshop
{
  public class CursorHlp
  {
    public static Cursor CreateCursor(UIElement element, Point hotSpot)
    {
      //element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
      //element.Arrange(new Rect(0, 0, element.DesiredSize.Width,
      //    element.DesiredSize.Height));
      //element.InvalidateVisual();

      int width = (int)element.RenderSize.Width;
      int height = (int)element.RenderSize.Height;
      var render = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
      render.Render(element);

      var encoder = new PngBitmapEncoder();
      encoder.Frames.Add(BitmapFrame.Create(render));
      using (var stream = new MemoryStream())
      {
        encoder.Save(stream);
        using (var bitmap = new System.Drawing.Bitmap(stream))
        {
          var cursor = InternalCreateCursor(bitmap, (int)(width * hotSpot.X), (int)(height * hotSpot.Y));
          return cursor;
        }
      }
    }

    static Cursor InternalCreateCursor(System.Drawing.Bitmap bitmap,
        int xHotSpot, int yHotSpot)
    {
      IconInfo iconInfo = new IconInfo();
      GetIconInfo(bitmap.GetHicon(), ref iconInfo);
      iconInfo.xHotspot = xHotSpot;
      iconInfo.yHotspot = yHotSpot;
      iconInfo.isIcon = false;

      IntPtr ptr = CreateIconIndirect(ref iconInfo);
      var handle = new SafeFileHandle(ptr, true);
      return CursorInteropHelper.Create(handle);
    }

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);

    [DllImport("user32.dll")]
    static extern IntPtr CreateIconIndirect(ref IconInfo icon);

    struct IconInfo
    {
      public bool isIcon;
      public int xHotspot;
      public int yHotspot;
      public IntPtr hbmMask;
      public IntPtr hbmColor;
    }

  }

  //static class CursorHlp
  //{
  //  public static Cursor ConvertToCursor(UIElement element, int width, int height, Point hotSpot)
  //  {
  //    element.Measure(new Size(width, height));
  //    element.Arrange(new Rect(0, 0, element.DesiredSize.Width,
  //        element.DesiredSize.Height));

  //    // Render to a bitmap
  //    var bitmapSource = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
  //    bitmapSource.Render(element);

  //    // Convert to System.Drawing.Bitmap
  //    var stride = ((width + 255) / 256) * 256;
  //    var pixels = new int[stride * height];
  //    bitmapSource.CopyPixels(pixels, stride, 0);
  //    var bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
  //    for (int y = 0; y < height; y++)
  //      for (int x = 0; x < width; x++)
  //        bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(pixels[y * stride + x]));

  //    // Save to .ico format
  //    var stream = new MemoryStream();
  //    var icon = System.Drawing.Icon.FromHandle(bitmap.GetHicon());
  //    icon.Save(stream);

  //    // Convert saved file into .cur format
  //    stream.Seek(2, SeekOrigin.Begin);
  //    stream.WriteByte(2);
  //    stream.Seek(10, SeekOrigin.Begin);
  //    stream.WriteByte((byte)(int)(hotSpot.X * width));
  //    stream.WriteByte((byte)(int)(hotSpot.Y * height));
  //    stream.Seek(0, SeekOrigin.Begin);

  //    // Construct Cursor
  //    var cursor = new Cursor(stream);
  //    return cursor;
  //  }
  //}
}
